package cn.ubeta.b2c.opengl;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;
import android.opengl.GLUtils;
import android.util.DisplayMetrics;

import cn.ubeta.b2c.R;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

public class EarthRenderer implements Renderer {

    private Sphere ball = null;
    private final float TOUCH_SCALE_FACTOR = 180.0f / 320;//角度缩放比例

    private Context mContext;

    public EarthRenderer(Context context) {
        mContext = context;
    }

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);

        gl.glShadeModel(GL10.GL_SMOOTH);

        gl.glClearDepthf(1.0f);

        gl.glEnable(GL10.GL_DEPTH_TEST);

        gl.glDepthFunc(GL10.GL_LEQUAL);
        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);

        gl.glEnable(GL10.GL_LIGHTING);
        initWhiteLight(gl, GL10.GL_LIGHT0, 0.5f, 0.5f, 0.5f);

        initMaterial(gl);

        ball = new Sphere(5, initTexture(gl, R.drawable.earth));
    }

    public void onDrawFrame(GL10 gl) {
        gl.glClearColor(0.96f, 0.93f, 0.91f, 1.0f);

        // Clears the screen and depth buffer.
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
        gl.glPushMatrix();
        ball.drawSelf(gl);
        gl.glPopMatrix();
    }

    public void onSurfaceChanged(GL10 gl, int width, int height) {
        // Sets the current view port to the new size.
        gl.glViewport(0, 0, width, height);
        // Select the projection matrix
        gl.glMatrixMode(GL10.GL_PROJECTION);
        // Reset the projection matrix
        gl.glLoadIdentity();
        // Calculate the aspect ratio of the window
        GLU.gluPerspective(gl, 45.0f, (float) width / (float) height, 0.1f, 100.0f);
        // Select the modelview matrix
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        // Reset the modelview matrix
        gl.glLoadIdentity();
    }


    /**
     * 设置白色灯光
     *
     * @param gl
     * @param cap
     * @param posX
     * @param posY
     * @param posZ
     */
    public void initWhiteLight(GL10 gl, int cap, float posX, float posY, float posZ) {
        gl.glEnable(cap);// 打开cap号灯

        // 环境光设置
        // F5EFEA
        //float[] ambientParams = { 1.0f, 1.0f, 1.0f, 1.0f };// 光参数 RGBA
        float[] ambientParams = { 0.96f, 0.93f, 0.91f, 1.0f };// 光参数 RGBA
        gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, ambientParams, 0);

        // 散射光设置
        float[] diffuseParams = { 0.96f, 0.93f, 0.91f, 1.0f };// 光参数 RGBA
        gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, diffuseParams, 0);

        // 反射光设置
        float[] specularParams = { 0.96f, 0.93f, 0.91f, 1.0f };// 光参数 RGBA
        gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_SPECULAR, specularParams, 0);

        float[] positionParams = { posX, posY, posZ, 1 };
        gl.glLightfv(cap, GL10.GL_POSITION, positionParams, 0);
    }

    /**
     * 由一个bitmap 创建一个纹理
     *
     * bitmap的大小限制：
     *
     * @param gl
     * @param resourceId
     * @return
     */
    public int initTexture(GL10 gl, int resourceId) {
        int[] textures = new int[1];
        gl.glGenTextures(1, textures, 0);
        int currTextureId = textures[0];
        gl.glBindTexture(GL10.GL_TEXTURE_2D, currTextureId);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);

        Bitmap bitmapTmp = BitmapFactory.decodeResource(mContext.getResources(), resourceId);
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmapTmp, 0);
        bitmapTmp.recycle();
        return currTextureId;
    }

    /**
     * 初始化白色材质
     *
     * 材质为白色时什么颜色的光照在上面就将体现出什么颜色
     *
     * @param gl
     */
    private void initMaterial(GL10 gl) {

        // 环境光为白色材质
        float ambientMaterial[] = { 1.0f, 1.0f, 1.0f, 1.0f };
        gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, ambientMaterial, 0);

        // 散射光为白色材质
        float diffuseMaterial[] = { 1.0f, 1.0f, 1.0f, 1.0f };
        gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE, diffuseMaterial, 0);

        // 高光材质为白色
        float specularMaterial[] = { 1f, 1f, 1f, 1.0f };
        gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_SPECULAR, specularMaterial, 0);
        gl.glMaterialf(GL10.GL_FRONT_AND_BACK, GL10.GL_SHININESS, 100.0f);
    }


    public void zoom(float newDist, float oldDist) {
        DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();

        float px = displayMetrics.widthPixels;
        float py = displayMetrics.heightPixels;

        ball.zoom += (newDist - oldDist) * (ball.maxZoom - ball.minZoom) / Math.sqrt(px * px + py * py) / 4;

        if (ball.zoom > ball.maxZoom) {
            ball.zoom = ball.maxZoom;
        } else if (ball.zoom < ball.minZoom) {
            ball.zoom = ball.minZoom;
        }
    }

    public void rotate(float xOffset, float yOffset) {
        if (ball != null) {
            ball.mAngleX += xOffset * TOUCH_SCALE_FACTOR; // 设置填充椭圆绕y轴旋转的角度
            ball.mAngleZ += xOffset * TOUCH_SCALE_FACTOR; // 设置填充椭圆绕y轴旋转的角度
            ball.mAngleY -= yOffset * TOUCH_SCALE_FACTOR; // 设置填充椭圆绕x轴旋转的角度
        }
    }
}
